using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Microsoft.Practices.CompositeUI;
using OrdersManager.Module.BusinessEntities;
using OrdersManager.Module.Constants;

namespace OrdersManager.Module.Services
{
	public class OrderService : IOrderService
	{
		private IOrderRepository _repository;
		private IOrderWorkflowManager _workflow;

		public OrderService([ServiceDependency] IOrderRepository repository,
		                    [ServiceDependency] IOrderWorkflowManager workflow)
		{
			_repository = repository;
			_workflow = workflow;
		}

		public void CancelOrder(Order order)
		{
			if (order == null)
				throw new ArgumentNullException("order");

			_workflow.NotifyOrderCancelled(order.Id);
		}

		public Order GetOrderById(Guid orderId)
		{
			if (_repository.Exists(orderId))
			{
				return _repository.GetById(orderId);
			}
			else
			{
				return null;
			}
		}

		public ICollection<OrderStatus> GetOrderPossibleStates(Order order)
		{
			return _workflow.GetOrderPossibleStates(order.Id);
		}

		public OrderCollection GetOrdersByState(OrderStatus stateMode)
		{
			ReadOnlyCollection<Guid> ids = _workflow.GetOrdersByState(stateMode);
			OrderCollection orders = new OrderCollection();
			
			foreach (Guid orderId in ids)
			{
				orders.Add(_repository.GetById(orderId));
			}
			
			return orders;
		}

		public void ProcessOrder(Order order)
		{
			if (order == null)
				throw new ArgumentNullException("order");

			_workflow.NotifyOrderProcessed(order.Id);
		}

		public void SaveOrder(Order order)
		{
			if (order == null)
				throw new ArgumentNullException("order");

			if (_repository.Exists(order.Id))
			{
				_repository.Update(order);
				_workflow.NotifyOrderUpdated(order.Id);
			}
			else
			{
				_repository.Insert(order);
                _workflow.CreateOrderWorkflow(order.Id);
				_workflow.NotifyOrderCreated(order.Id);
			}
		}

		public void ShipOrder(Order order)
		{
			if (order == null)
				throw new ArgumentNullException("order");

			_workflow.NotifyOrderShipped(order.Id);
		}
	}
}